Add internal ot_openat_read_stream() helper
authorColin Walters <walters@verbum.org>
Wed, 7 Jan 2015 13:41:45 +0000 (08:41 -0500)
committerColin Walters <walters@verbum.org>
Wed, 7 Jan 2015 13:41:45 +0000 (08:41 -0500)
We had two cases which were creating an input stream using openat().

src/libostree/ostree-repo-commit.c
src/libostree/ostree-sysroot-deploy.c
src/libotutil/ot-fs-utils.c
src/libotutil/ot-fs-utils.h

index c83c4bd83fea109138264d0d5b34e64f898c1b5e..ca52704efb535611f5d28c72c4e1135820213495 100644 (file)
@@ -2112,13 +2112,9 @@ write_directory_content_to_mtree_internal (OstreeRepo                  *self,
                 }
               else
                 {
-                  int filefd = openat (dfd_iter->fd, name, O_RDONLY | O_CLOEXEC, 0);
-                  if (filefd == -1)
-                    {
-                      gs_set_error_from_errno (error, errno);
-                      goto out;
-                    }
-                  file_input = (GInputStream*)g_unix_input_stream_new (filefd, TRUE);
+                  if (!ot_openat_read_stream (dfd_iter->fd, name, FALSE,
+                                              &file_input, cancellable, error))
+                    goto out;
                 }
             }
 
index cdf5e182559db33df2c3051863038cf98ce86a44..d5c6811e33807d95088013a7497c5aab7ce0d98c 100644 (file)
@@ -52,18 +52,13 @@ copy_one_file_fsync_at (int              src_parent_dfd,
   if (S_ISREG (stbuf->st_mode))
     {
       /* Note the objects take ownership of the fds */
-      int src_fd = -1;
       int dest_fd = -1;
       gs_unref_object GInputStream *in = NULL;
       gs_unref_object GOutputStream *out = NULL;
 
-      src_fd = openat (src_parent_dfd, name, O_RDONLY | O_NOFOLLOW | O_NOCTTY | O_NOATIME | O_CLOEXEC);
-      if (src_fd == -1)
-        {
-          gs_set_error_from_errno (error, errno);
-          goto out;
-        }
-      in = g_unix_input_stream_new (src_fd, TRUE);
+      if (!ot_openat_read_stream (src_parent_dfd, name, FALSE,
+                                  &in, cancellable, error))
+        goto out;
 
       dest_fd = openat (dest_parent_dfd, name, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC,
                         stbuf->st_mode);
index 3ca623526e6d1d0034acfe26d690dd58c5143d0f..7137b829657d51934ca9e12046474e3a52107ed2 100644 (file)
@@ -23,6 +23,7 @@
 #include "ot-fs-utils.h"
 #include "libgsystem.h"
 #include <attr/xattr.h>
+#include <gio/gunixinputstream.h>
 
 int
 ot_opendirat (int dfd, const char *path, gboolean follow)
@@ -143,3 +144,47 @@ ot_readlinkat_gfile_info (int             dfd,
   return ret;
 }
 
+
+/**
+ * ot_openat_read_stream:
+ * @dfd: Directory file descriptor
+ * @path: Subpath
+ * @follow: Whether or not to follow symbolic links
+ * @out_istream: (out): Return location for input stream
+ * @cancellable: Cancellable
+ * @error: Error
+ *
+ * Open a file for reading starting from @dfd for @path.
+ * The @follow parameter determines whether or not to follow
+ * if the last element of @path is a symbolic link.  Intermediate
+ * symlink path components are always followed.
+ */
+gboolean
+ot_openat_read_stream (int             dfd,
+                       const char     *path,
+                       gboolean        follow,
+                       GInputStream  **out_istream,
+                       GCancellable   *cancellable,
+                       GError        **error)
+{
+  gboolean ret = FALSE;
+  int fd = -1;
+  int flags = O_RDONLY | O_NOCTTY | O_CLOEXEC;
+
+  if (!follow)
+    flags |= O_NOFOLLOW;
+
+  do
+    fd = openat (dfd, path, flags, 0);
+  while (G_UNLIKELY (fd == -1 && errno == EINTR));
+  if (fd == -1)
+    {
+      gs_set_error_from_errno (error, errno);
+      goto out;
+    }
+
+  *out_istream = g_unix_input_stream_new (fd, TRUE);
+  ret = TRUE;
+ out:
+  return ret;
+}
index e0bb4003e1ef97ab478aefa7c1c0b13700aff751..41389df2079645469e8dbbb0842c21e4f70f2915 100644 (file)
@@ -50,5 +50,12 @@ gboolean ot_readlinkat_gfile_info (int             dfd,
                                    GCancellable   *cancellable,
                                    GError        **error);
 
+gboolean ot_openat_read_stream (int             dfd,
+                                const char     *path,
+                                gboolean        follow,
+                                GInputStream  **out_istream,
+                                GCancellable   *cancellable,
+                                GError        **error);
+
 G_END_DECLS